package com.situ.mall.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.situ.mall.api.user.UserClient;
import com.situ.mall.common.constants.MqConstant;
import com.situ.mall.common.util.ExcelUtil;
import com.situ.mall.common.util.MultiDelayMessage;
import com.situ.mall.common.util.Result;
import com.situ.mall.order.mapper.CartMapper;
import com.situ.mall.order.mapper.OrderItemMapper;
import com.situ.mall.order.pojo.query.OrderInfoQuery;
import com.situ.mall.order.pojo.query.OrderQuery;
import com.situ.mall.order.pojo.vo.CartVO;
import com.situ.mall.order.pojo.vo.OrderCountVO;
import com.situ.mall.order.pojo.vo.OrderInfoExcelVO;
import com.situ.mall.order.pojo.vo.OrderInfoVO;
import com.situ.mall.order.service.ICartService;
import com.situ.mall.pojo.entity.order.OrderInfo;
import com.situ.mall.order.mapper.OrderInfoMapper;
import com.situ.mall.order.service.IOrderInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.situ.mall.pojo.entity.order.OrderItem;
import com.situ.mall.pojo.entity.user.User;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author Sun Huijuan
 * @since 2024-10-14
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService {
	@Autowired
	private OrderInfoMapper orderInfoMapper;
	@Autowired
	private OrderItemMapper orderItemMapper;
	@Autowired
	private ICartService cartService;
	@Autowired
	private CartMapper cartMapper;
	@Autowired
	private UserClient userClient;
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	@Override
	public void add(OrderInfo orderInfo) {
		//orderInfo里面有userId和addressId
		if(orderInfo.getUserId()!=null){
			//获取用户名
			Result<User> userResult = userClient.selectById(orderInfo.getUserId());
			if (userResult != null) {
				User user = userResult.getData();
				orderInfo.setUserName(user.getName());
			}
		}
		//1.生成订单编号order_no，规则使用：时间戳+随机生成数生成订单号  或用UUID截取后6位
		//格式化随机数，确保为6位
		String random = String.format("%06d", new Random().nextInt(1000000));
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String orderNo = simpleDateFormat.format(new Date())+random;
		orderInfo.setOrderNo(orderNo);
		//2.查找购物车中用户要结算的商品，然后过滤出checked=1的
		List<CartVO> cartVOList = cartService.selectByUserId(orderInfo.getUserId());
		cartVOList=cartVOList.stream().filter(cartVO -> cartVO.getChecked()==1).collect(Collectors.toList());
		//3.每遍历一个cartVO，就往order_item表里插入数据
		BigDecimal totalAmount=new BigDecimal(0);
		for(CartVO cartVO:cartVOList){
			OrderItem orderItem = new OrderItem();
			//属于哪个订单
			orderItem.setOrderNo(orderNo);
			orderItem.setProductId(cartVO.getProductId());
			orderItem.setProductName(cartVO.getProductName());
			orderItem.setQuantity(cartVO.getQuantity());
			orderItem.setUnitPrice(cartVO.getProductPrice());
			orderItem.setProductImage(cartVO.getProductImage());
			orderItemMapper.insert(orderItem);
			//累加order_item中每个订单的每个商品总价格：价格*数量
			BigDecimal itemAmount=orderItem.getUnitPrice().multiply(new BigDecimal(cartVO.getQuantity()));
			totalAmount=totalAmount.add(itemAmount);
			//删除购物车中的已经购买的商品信息
			cartMapper.deleteById(cartVO.getId());
			//生成订单减库存【feign远程调用product_service】
			
		}
		orderInfo.setTotalAmount(totalAmount);
		orderInfoMapper.insert(orderInfo);
		//调用短信服务通知用户
		
		//延迟检查订单状态消息
		MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderInfo.getId(), 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L);
		int delayValue = msg.removeNextDelay().intValue();
		rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, MqConstant.DELAY_ORDER_ROUTING_KEY, msg, new MessagePostProcessor() {
			@Override
			public Message postProcessMessage(Message message) throws AmqpException {
				message.getMessageProperties().setDelay(delayValue);
				return message;
			}
		});
	}
	
	@Override
	public List<OrderInfoVO> list(OrderInfoQuery orderInfoQuery) {
		List<OrderInfoVO> orderInfoVOList=orderInfoMapper.list(orderInfoQuery);
		for(OrderInfoVO orderInfoVO:orderInfoVOList){
			Integer count=orderItemMapper.selectTotalNum(orderInfoVO.getOrderNo());
			orderInfoVO.setTotalNum(count);
		}
		return orderInfoVOList;
	}
	
	@Override
	public OrderInfoVO selectById(Long id) {
		OrderInfo orderInfo=orderInfoMapper.selectById(id);
		OrderInfoVO orderInfoVO=new OrderInfoVO();
		BeanUtils.copyProperties(orderInfo, orderInfoVO);
		List<OrderItem> list=orderItemMapper.selectList(new QueryWrapper<OrderItem>().eq("order_no", orderInfo.getOrderNo()));
		orderInfoVO.setOrderItemList(list);
		return orderInfoVO;
	}
	
	@Override
	public void updateStatus(Long id, Integer status) {
		UpdateWrapper<OrderInfo> updateWrapper = new UpdateWrapper<>();
		updateWrapper.set("order_status", status).eq("id", id);
		orderInfoMapper.update(updateWrapper);
		
	}
	
	@Override
	public IPage<Map<String, Object>> selectList(OrderInfoQuery orderInfoQuery) {
		QueryWrapper<Map<String,Object>> wrapper=new QueryWrapper<>();
		wrapper.eq(!ObjectUtils.isEmpty(orderInfoQuery.getUserId()), "oi.user_id", orderInfoQuery.getUserId());
		Page<Map<String,Object>> page=new Page<>(orderInfoQuery.getPage(),orderInfoQuery.getLimit());
		return orderInfoMapper.selectListPortal(page,wrapper);
	}
	
	@Override
	public List<OrderCountVO> selectOrderCount() {
		return orderInfoMapper.selectOrderCount();
	}
	
	@Override
	public BigDecimal selectSaleCount() {
		return orderInfoMapper.selectSaleCount();
	}
	
	@Override
	public void exportExcel(HttpServletResponse response) {
		List<OrderInfoVO> list=orderInfoMapper.selectAll();
		List<OrderInfoExcelVO> orderInfoExcelVOList = new ArrayList<>();
		for (OrderInfoVO orderInfoVO : list) {
			OrderInfoExcelVO orderInfoExcelVO = new OrderInfoExcelVO();
			BeanUtils.copyProperties(orderInfoVO, orderInfoExcelVO);
			orderInfoExcelVOList.add(orderInfoExcelVO);
		}
		ExcelUtil.exportExcel(response,orderInfoExcelVOList,OrderInfoExcelVO.class,"订单");
	}
	
	
}
